package koala.kuangjiademo.util;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.content.LocalBroadcastManager;

import com.dhy.xintent.XIntent;

import org.apache.commons.lang3.ArrayUtils;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

public class FlowUtil {

    public static void register(Activity activity) {
        FinishActivityReceiver receiver = new FinishActivityReceiver(activity);
        LocalBroadcastManager.getInstance(activity).registerReceiver(receiver, receiver.getIntentFilter());
        map.put(activity, receiver);
    }

    public static void unregister(Activity activity) {
        LocalBroadcastManager.getInstance(activity).unregisterReceiver(map.remove(activity));
    }

    public static void finishIncludeSelf(Context context, Class<? extends Activity>... activities) {
        finish(context, activities);
        if (context instanceof Activity) ((Activity) context).finish();
    }

    public static void finish(Context context, Class<? extends Activity>... activities) {
        for (Class<? extends Activity> activity : activities) {
            sendBroadcast(context, new Intent(getFinishAction(activity)));
        }
    }

    public static void finishAllExceptSelf(Context context, Class<? extends Activity>... excepts) {
        if (context instanceof Activity) {
            excepts = ArrayUtils.add(excepts, ((Activity) context).getClass());
        }
        finishAll(context, excepts);
    }

    public static void finishAll(Context context, Class<? extends Activity>... excepts) {
        Intent intent = new Intent(ACTION_FINISH_ALL);
        XIntent.putSerializableExtra(intent, (Serializable) excepts);
        sendBroadcast(context, intent);
    }

    private static void sendBroadcast(Context context, Intent intent) {
        LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
    }

    private static String getFinishAction(Class<? extends Activity> cls) {
        return cls.getName() + ".action.finish";
    }

    private static final String ACTION_FINISH_ALL = FlowUtil.class.getName() + ".action.finish.all";
    private static final Map<Activity, FinishActivityReceiver> map = new HashMap<>();

    private static class FinishActivityReceiver extends BroadcastReceiver {
        private final Activity activity;
        private final String ACTION_FINISH;
        private final IntentFilter intentFilter;

        FinishActivityReceiver(Activity activity) {
            this.activity = activity;
            ACTION_FINISH = getFinishAction(activity.getClass());
            intentFilter = new IntentFilter();
            intentFilter.addAction(ACTION_FINISH);
            intentFilter.addAction(ACTION_FINISH_ALL);
            LocalBroadcastManager.getInstance(activity).registerReceiver(this, intentFilter);
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(ACTION_FINISH)) {
                activity.finish();
            } else if (intent.getAction().equals(ACTION_FINISH_ALL)) {
                Class<?>[] excepts = XIntent.readSerializableExtra(intent, Class[].class);
                if (!ArrayUtils.contains(excepts, activity.getClass())) activity.finish();
            }
        }

        public IntentFilter getIntentFilter() {
            return intentFilter;
        }
    }
}
